import {
  getBarcodeInfo,
  getNotesDetail,
  saveNotes,
  msgCheck
} from '../../common/api/index';
import {
  toolbar,
  RESOURSES,
  NOTES_CATE,
  TOOL_BAR
} from '../../common/config'
import {
  tz,
  toast,
  vbs,
  DateFormat,
  getIP,
  getLocationInfo,
  getWeather,
  getUserInfo,
  back,
  sleep,
  delay
} from "../../common/utils"
const computedBehavior = require('miniprogram-computed'); //computed 拓展
const watchBehavior = require("miniprogram-watch"); //watch拓展

import {
  wxp,
  formateSeconds,
  getSiffix,
  discernORC
} from "../../common/utils"; //API Promise化拓展 
var plugin = requirePlugin("WechatSI"); //同声传译插件
Page({
  behaviors: [computedBehavior, watchBehavior],
  data: {
    content: {
      html: '',
      title: '',
      barcode: '', //
      resourse: {
        records: [],
        images: [],
        videos: [],
      }
    },
    topbar: {},
    tags: wx.getStorageSync('TAGS') || ["语文", "数学", "英语", "物理", "计算机", "化学"],
    tempTag: '',
    showTagPopup: false,
    resourses: RESOURSES,
    curResourse: 0, //当前显示资源
    localtion: null,
    date: '2020年08月28日 周一',
    weatherInfo: {}, //天气信息
    localtionInfo: {}, //位置信息
    operation: 0, //操作 用于控制撤销    
    systemInfo: wx.getSystemInfoSync(),
    placeholder: "输入正文",
    animationStatus: false,
    voiceRecordMode: false, //语音模式 false 录音   true语音转文字
    recordSec: 0,
    keybordHeight: 0,
    footerHeight: 0,
    recordTimer: null,
    listening: false,
    saveing: false,
    curtool: -1, //当前操作   

    format: {
      bold: false,
      italic: false,
      underline: false
    },
    showPopup: false,
    showSpeechPopup: false,
    ocrResult: [], //图像识别返回值
    speechResult: '', //语音识别返回值
    ocring: false,
    orcResultText: '', //图像识别返回文本
    speechResultText: '', //语音识别返回文本
    toolbar: TOOL_BAR,
    //图片部分
    images: wx.getStorageSync('IMAGES') || [],

  },
  watch: {
    curtool(nv, ov) {
      setTimeout(() => {
        this.watchFooterViewHeight();
      }, 100)
    }
  },
  computed: {
    date(data) {
      let date = DateFormat(new Date(), "yyyy年MM月dd日 w")
      return date;

    },
    //资源数量统计
    // resourseCount(data){
    //  let  recordCount = data.content.records.length || 0 ;
    //  let videosCount = data.content.videos.length || 0
    //    return recordCount + videosCount
    // },
    showToolbarArea(data) {
      return data.curtool === -1 ? false : !data.toolbar[data.curtool]['hidden']
    },
    animationStatus(data) {
      return data.listening;
    },
    //录音时长时间显示
    recordTime(data) {
      return formateSeconds(data.recordSec)
    },
    //当前选择的文字
    chosedText(data) {
      let checkedItem = data.ocrResult.filter(item => item.checked);
      checkedItem = checkedItem.map(item => item.text)
      let text = checkedItem.reduce((c, p) => `${c}${p}`, '')
      return text
    }

  },

  async onLoad(options) {
    let {
      type,
      id
    } = options;
    let types = [null, ...NOTES_CATE]; //首位插入个null 因为type从1开始  
    if (!id) { }
    const title = `新建${types[type].title || '文档'}`; //默认标题
    this.setData({
      type: type * 1,
      id,
      ['content.title']: title
    })
    this.initRecorderManager(); //全局录音管理器初始化 
    this.initTopBar(); //顶部栏初始化
    //页面标题
    wx.setNavigationBarTitle({
      title
    })

  },

  /**
   * 初始化内容Content
   * @param {int} id  如果有ID则是编辑 如果没id则是新建
   */
  async initContent(id) {
    let content;
    if (id) { //编辑模式 从数据库拿文章数据
      let cache = wx.getStorageSync(`EDITOR_${id}`);
      wx.setNavigationBarTitle({
        title: '编辑'
      });
      if (cache) {
        let editTime = DateFormat(new Date(cache.time), "yyyy-MM-dd hh:mm");
        let {
          confirm
        } = await wxp.showModal({
          title: '提示',
          content: `检测到该文档有于${editTime}编辑的未保存内容，是否加载`,
          confirmText: '加载',
          cancelText: '不加载'
        });
        if (confirm) {
          content = cache.content
        } else {
          content = await getNotesDetail(id);
        }
      } else {
        content = await getNotesDetail(id);
      }
      this.setData({
        type: content.type
      }) //保存文档类型
    } else { //新建模式 从缓存拿文章数据
      const defaultContent = this.data.content;
      content = wx.getStorageSync("EDITOR") || defaultContent;
      // content.videos = content.videos || [];
    }
    this.setData({
      content
    });
    this.editorCtx.setContents(content)

  },
  //初始化监听器
  initListeners() {
    //键盘高度监听事件
    wx.onKeyboardHeightChange(res => {
      let keybordHeight = res.height
      this.setData({
        keybordHeight: keybordHeight ? 1 : keybordHeight
      })
    })
  },
  //页面准备好了
  onReady() {
    this.watchFooterViewHeight();
  },
  //初始化顶部栏
  async initTopBar() {
    let {
      type,
      id
    } = this.data;
    let {
      topbar
    } = NOTES_CATE[type - 1];
    let obj = {};
    topbar.forEach(item => {
      obj[item] = true
    })
    this.setData({
      topbar: obj
    })
    if (obj.code && !id) { //如果该页面需要条形码
      await getBarcodeInfo();
      let {
        confirm
      } = await wx.showModal({
        title: '输入条形码',
        content: '是否立即输入条形码',
        confirmText: '扫描',
        cancelText: '稍后'
      });
      if (confirm) {
        this.handleScanCode();
      }
    }
    if (obj.weather || obj.localtion) { //如果需要天气或地理位置
      let weatherInfo = await getWeather();
      this.setData({
        weatherInfo
      })
    }

  },
  //标签输入
  handleInputTag({
    detail: {
      value
    }
  }) {
    this.setData({
      tempTag: value
    })
  },
  //显示标签选择
  handleShowChooseTag() {
    this.setData({
      showTagPopup: true
    })
  },
  //插入标签
  handleConfirmTag() {
    let {
      tempTag,
      tags = []
    } = this.data;
    let index = tags.findIndex(item => item === tempTag);
    if (index !== -1) {
      tags.splice(index, 1);
    }
    tags.unshift(tempTag)
    this.setData({
      ['content.tag']: tempTag,
      tags,
      showTagPopup: false
    });
    wx.setStorageSync('TAGS', tags)
  },
  //选择标签
  handleChooseTag({
    currentTarget: {
      dataset
    }
  }) {

    let {
      name
    } = dataset;
    this.setData({
      tempTag: name
    })
  },
  //取消选择标签
  handleCancelChooseTag() {
    this.setData({
      showTagPopup: false
    })
  },
  //移除标签
  handleRemoveTag({
    currentTarget: {
      dataset
    }
  }) {
    let {
      tags
    } = this.data;
    let {
      index
    } = dataset
    tags.splice(index, 1)
    this.setData({
      tags
    });
    wx.setStorageSync('TAGS', tags)
  },
  //输入条形码
  async handleScanCode() {
    let res = await wxp.scanCode({
      scanType: ['barCode']
    }).catch(err => {
      console.error(`错误:`, err);

    })
    let {
      result
    } = res;
    this.setData({
      ['content.barcode']: result
    })
  },
  //标题输入框 输入事件
  handleTitleInput({
    detail: {
      value
    }
  }) {
    this.setData({
      ['content.title']: value
    })
  },
  //保存
  async handleSave() {
    this.setData({
      saveing: true
    })
    let {
      content,
      weatherInfo,
      date,
      type,
      localtion
    } = this.data;

    let userInfo = await getUserInfo();
    content.weather = JSON.parse(JSON.stringify(weatherInfo, ["text", "icon", "temp"])); //天气信息存储
    content.localtion = JSON.parse(JSON.stringify(weatherInfo, ["nation", "province", "city", "district"])); //地理信息存储
    content.address = localtion
    content.user = {
      openid: userInfo.openid,
      ...userInfo.users
    };
    // content.resourse = {
    //    records:content.records,
    //    videos:content.videos
    // };
    content.type = type;
    // delete content.records;
    content.date = date.split(" ");
    content.viewers = [];
    // 检测内容是否安全
    let check = await msgCheck(content)
    if (!check[1]) {
      if (check[0] == "title") {
        wx.showModal({
          confirmText: '立即修改',
          content: '您的标题中有违规内容',
          showCancel: false,
          title: '系统警告',
        })
      } else if (check[0] == "html")
        wx.showModal({
          confirmText: '立即修改',
          content: '您的详情中有违规内容',
          showCancel: false,
          title: '系统警告',
        })
      this.setData({
        saveing: false
      })
      return false
    }
    let res = await saveNotes(content)
    if (content.id) { //编辑保存后的处理
      wx.removeStorageSync(`EDITOR_${content.id}`);
      //获取上一个页面
      let pages = getCurrentPages();
      let prevPage = pages[pages.length - 2]; //获取到A页面
      toast("保存成功", "success")
      await prevPage.loadData(content.id);
      back();
    } else { //新建保存
      wx.removeStorageSync(`EDITOR`); //移除缓存
      wx.setStorageSync('isSave', {
        type
      })
      toast("保存成功", "success");
      await delay(1000)
      back();


    }
    this.setData({
      saveing: false
    })


  },
  handleEditorScroll(e) {
    let {
      scrollTop
    } = e.detail;
    let opacity = 1 - (scrollTop / 160);
    this.setData({
      opacity: opacity < 0 ? 0 : opacity
    })
  },
  //检测底部面板高度
  watchFooterViewHeight() {
    wx.createSelectorQuery().select('#footer').boundingClientRect((rect) => {
      let footerHeight = rect.height;
      this.setData({
        footerHeight
      })
      // rect.id      // 节点的ID
      // rect.dataset // 节点的dataset
      // rect.left    // 节点的左边界坐标
      // rect.right   // 节点的右边界坐标
      // rect.top     // 节点的上边界坐标
      // rect.bottom  // 节点的下边界坐标
      // rect.width   // 节点的宽度
      // rect.height  // 节点的高度
    }).exec()
  },
  //编辑器点击
  handleEditTap() {
    this.handleHideSwiper();
  },

  //更新内容缓存
  updateContentCache() {
    let {
      content
    } = this.data;
    if (content.id) {
      wx.setStorageSync(`EDITOR_${content.id}`, {
        content,
        time: new Date().getTime()
      })
      return
    }

    wx.setStorageSync('EDITOR', content)

    // console.log("当前内容",content)
  },
  handleEditInput({
    detail
  }) {
    let {
      html
    } = detail;
    this.setData({
      [`content.html`]: html
    });
    this.updateContentCache();
  },
  //插入分割线
  handleInsertDivider() {
    this.editorCtx.insertDivider({
      success: function () {
        console.log('insert divider success')
      }
    })
  },
  //移除位置
  async handleDeleteLocaltion() {
    let {
      tapIndex
    } = await wx.showActionSheet({
      itemList: ["移除", "取消"],
    })
    if (!tapIndex) {
      this.setData({
        localtion: null
      })
    }
  },
  //插入位置
  async handleChooseAddress() {
    let {
      name,
      address,
      latitude,
      longitude
    } = await wxp.chooseLocation({});
    this.setData({
      localtion: {
        name,
        address,
        latitude,
        longitude
      }
    })
  },
  //分词组件内容变化
  handleBigbangChange({
    detail
  }) {
    this.setData({
      orcResultText: detail
    })
  },
  //分词组件返回结果复制
  handleCopyText() {
    let {
      orcResultText
    } = this.data;
    if (!orcResultText.length) {
      toast("请选择文字内容")
      return
    }
    wx.setClipboardData({
      data: orcResultText,
      success: () => {
        toast("已复制")
      }
    })
    this.setData({
      showPopup: false
    })
  },
  //分词组件返回结果插入editor
  handleInsertText() {
    let {
      orcResultText
    } = this.data;
    if (!orcResultText.length) {
      toast("请选择文字内容")
      return
    }
    this.editorCtx.insertText({
      text: orcResultText
    })
    this.setData({
      showPopup: false,
      showSpeechPopup: false
    })
  },
  //显示最近一次OCR识别结果
  handleShowOCRHistory() {
    // console.log("触发showPopup")
    if (!this.data.ocrResult.length) {
      toast("暂无识别记录");
      return;
    }
    this.setData({
      showPopup: false,
      showSpeechPopup: false
    })
  },
  //扫描OCR
  async handleScanOCR(filePath) {
    wx.showLoading({
      title: '识别中...'
    })
    try {
      this.setData({
        ocring: true
      })
      let ocrResult = await discernORC(filePath, true);
      wx.hideLoading();
      this.setData({
        ocrResult,
        showPopup: true,
        ocring: false
      })
    } catch (e) {
      console.error("识别失败", e)
      toast("识别失败")
      wx.hideLoading()
    }
  },

  //编辑器状态改变
  handleStatusChange(e) {
    // console.log("handleStatusChange", e)
  },
  // 工具栏点击
  handleToolBarTap({
    currentTarget
  }) {
    let {
      index
    } = currentTarget.dataset;
    this.setData({
      curtool: index
    })
  },
  //颜色选择器改变
  handleColorChange({
    detail
  }) {
    /**
     * isBack 是否为背景色
     * value  颜色值 16进制
     */
    let {
      isBack,
      value
    } = detail;
    this.handleFormat({
      target: {
        dataset: {
          name: isBack ? 'backgroundColor' : 'color',
          value
        }
      }
    })
  },
  // 撤销
  handleUndo() {
    this.editorCtx.undo()

  },
  //重做
  handleRedo() {
    this.editorCtx.redo()
  },
  //收起面板
  handleHideSwiper() {
    this.setData({
      curtool: this.data.curtool === -1 ? 0 : -1
    })

  },
  //Editor获取焦点 从中获取键盘高度
  handleEditorFocus(e) {
    // console.log("获取键盘高度",e)
  },
  //富文本样式格式化
  handleFormat({
    target: {
      dataset
    }
  }) {
    let {
      name,
      value
    } = dataset;
    if (name) {
      this.editorCtx.format(name, value);
      vbs()
      if (this.data.format[name] !== undefined) {
        // this.setData({
        //   [`format.${name}`]:!this.data.format[name]
        // })
      } else {

      }


    }
  },
  //插入图片
  async handleChooseImage(context) {
    // 插入图片
    const that = this
    let {
      tempFilePaths
    } = await wxp.chooseImage({
      count: 8
    }); //选择图片
    wx.showLoading({
      title: '请稍后...'
    })
    let fileList = await Promise.all(tempFilePaths.map(async filePath => { //上传图片列表
      let cloudPath = `images/${new Date().getTime()}${getSiffix(filePath)}`; //目标存储路径
      let {
        fileID
      } = await wx.cloud.uploadFile({
        cloudPath,
        filePath
      });
      return fileID
    }));
    let {
      fileList: srcs
    } = await wx.cloud.getTempFileURL({
      fileList
    }) //临时链接获取
    srcs = srcs.map(item => ({
      src: item.tempFileURL,
      fileID: item.fileID
    })) //格式转换
    let {
      images = []
    } = this.data.content.resourse;
    images = images.concat(srcs);
    this.setData({
      ['content.resourse.images']: images
    })
    wx.hideLoading();
    this.updateContentCache()
  },
  //插入视频
  async handleChooseVideo() {
    let {
      tempFilePath: filePath
    } = await wx.chooseVideo();
    let cloudPath = `videos/${new Date().getTime()}${getSiffix(filePath)}`; //目标存储路径
    let {
      fileID
    } = await wx.cloud.uploadFile({
      cloudPath,
      filePath
    });
    let {
      fileList: [{
        tempFileURL
      }]
    } = await wx.cloud.getTempFileURL({
      fileList: [fileID]
    });
    let {
      videos = []
    } = this.data.content.resourse;
    videos.push({
      src: tempFileURL,
      fileID
    })
    this.setData({
      ['content.resourse.videos']: videos
    })
    this.updateContentCache();
  },
  //删除视频
  async handleRemoveVideo({
    target
  }) {

    let {
      dataset
    } = target;
    let {
      index,
      fileid
    } = dataset

    let {
      confirm
    } = await wxp.showModal({
      title: '删除视频',
      content: '是否确认删除'
    })
    if (!confirm) return;
    let {
      videos
    } = this.data.content;
    let res = await wx.cloud.deleteFile({
      fileList: [fileid]
    })
    videos.splice(index, 1);
    this.setData({
      [`content.videos`]: videos
    });
    this.updateContentCache();
  },
  // 删除图片
  handleDeleteImage({
    currentTarget: {
      dataset
    }
  }) {
    let {
      index
    } = dataset;
    let {
      images
    } = this.data.content.resourse;
    images.splice(index, 1);
    this.setData({
      ['content.resourse.images']: images
    });
    this.updateContentCache();
  },
  //图片操作
  async handleImagesOper({
    target: {
      dataset
    }
  }) {
    let {
      index,
      url
    } = dataset;
    let {
      images
    } = this.data.content.resourse;
    let {
      tapIndex
    } = await wxp.showActionSheet({
      itemList: ["预览", "插入", "OCR识别"],
    })
    switch (tapIndex) {
      case 0: //图片预览
        wx.previewImage({
          current: images[index].src,
          urls: images.map(item => item.src),
        })
        break;
      case 1: //图片插入
        this.editorCtx.insertImage({
          src: url,
          data: {
            id: 'abcd',
            role: 'god'
          },
          width: '50%',
          extClass: 'radius shadow',
        })
        break;
      case 2: //图片识别
        this.handleScanOCR(url);
        break;
    }
  },
  //切换工具栏
  handleToolbarChange({
    detail
  }) {
    vbs();
    let {
      current
    } = detail
    this.setData({
      curtool: current
    })



  },
  //切换资源列表
  handleSwitchResourse({
    target: {
      dataset
    }
  }) {
    let {
      index
    } = dataset;
    this.setData({
      curResourse: index
    })
    vbs()
  },
  //切换录音模式
  handleSwitchVoiceMode() {
    vbs()
    this.setData({
      voiceRecordMode: !this.data.voiceRecordMode
    })
  },
  //开始说话
  touchStartSpeak() {
    if (!this.data.voiceRecordMode) {
      return;
    }
    vbs();
    this.manager.start();
    this.setData({
      animationStatus: true
    })
  },
  // 结束说话
  touchEndSpeak() {
    if (!this.data.voiceRecordMode) {
      return;
    }
    this.manager.stop();
    let showSpeechPopup = !!this.data.speechResult.length;
    this.setData({
      animationStatus: false,
      showSpeechPopup
    })

  },

  // 开始||停止录音
  handleStartReocrd() {
    if (this.data.voiceRecordMode) {
      return;
    }

    if (this.data.listening) {
      this.manager.stop();
      this.setData({
        listening: false
      })
    } else {
      this.manager.start({
        lang: "zh_CN"
      });
    }
  },
  //删除录音
  async handleRemoveVoice({
    target
  }) {
    let {
      dataset: {
        index,
        id
      }
    } = target;

    let {
      confirm
    } = await wxp.showModal({
      title: '删除录音',
      content: '是否确认删除'
    })
    if (!confirm) return;
    let records = this.data.content.resourse.records
    records.splice(index, 1);
    let res = await wx.cloud.deleteFile({
      fileList: [id]
    })
    this.setData({
      [`content.resourse.records`]: records
    });
    this.updateContentCache();
  },

  // 编辑器准备好了
  onEditorReady() {
    wx.createSelectorQuery().select('#editor').context(res => {
      this.editorCtx = res.context;
      this.initContent(this.data.id);
    }).exec()
  },

  /**
   * 录音管理器初始化
   */
  initRecorderManager() {
    this.manager = plugin.getRecordRecognitionManager(); //创建录音
    this.manager.onRecognize = (res) => {
      let {
        voiceRecordMode
      } = this.data; //获取当前模式  录音或者说话
      if (voiceRecordMode) {
        vbs();
        this.setData({
          speechResult: res.result
        })
      }

    }
    this.manager.onStop = (res) => {
      let {
        voiceRecordMode
      } = this.data; //获取当前模式  录音或者说话
      if (voiceRecordMode) return //语音识别模式 不存储录音文件

      this.setData({
        listening: false,
        recordSec: 0
      });
      clearInterval(this.recordTimer); //清除上一次录音的时钟
      this.uploadRecordFile(res);
    }
    this.manager.onStart = (res) => {
      this.setData({
        listening: true
      })
      let {
        voiceRecordMode
      } = this.data; //获取当前模式  录音或者说话
      if (voiceRecordMode) return //语音识别模式 不开启计时器

      this.recordTimer = setInterval(_ => {
        let sec = this.data.recordSec;
        this.setData({
          recordSec: sec + 1
        })

      }, 1000)

    }
    this.manager.onError = (res) => {

      console.error("error msg", res.msg)
    }

    this.setData({
      speaking: true
    })
  },
  /**
   * 上传录音文件
   * @param {*} tempFilePath 临时文件地址
   * @param {*} duration     录音时长 单位ms  需要做/1000处理 
   * @param {*} fileSize     文件尺寸 单位 kb 
   * @returns Promise
   */
  async uploadRecordFile({
    tempFilePath: filePath,
    duration,
    fileSize
  }) {
    let cloudPath = `record/${new Date().getTime()}${getSiffix(filePath)}`; //目标存储路径
    let {
      fileID
    } = await wx.cloud.uploadFile({
      cloudPath,
      filePath
    }); //上传文件
    let {
      records
    } = this.data.content.resourse; //录音列表
    records.unshift({
      fileID,
      duration: (duration / 1000),
      fileSize
    }) //本地加入本次录音文件
    this.setData({
      [`content.resourse.records`]: records
    });
    this.updateContentCache();
  },

})